package star.cloud.asme.asmePerson.asmePersonTrain.asmePersonTrainCourse;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import star.cloud.asme.asmePerson.asmePersonTrain.asmePersonTrainRecord.AsmePersonTrainRecord;
import star.cloud.asme.asmePerson.asmePersonTrain.asmePersonTrainRecord.AsmePersonTrainRecordMapper;
import star.cloud.asme.base.dto.Result;
import star.cloud.asme.base.file.fileInfo.FileInfo;
import star.cloud.asme.base.file.fileInfo.FileInfoMapper;
import star.cloud.asme.base.mybatis.IBaseServiceImpl;
import star.cloud.asme.base.utils.ObjectsUtil;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.UUID;


@Service
@Slf4j
@RequiredArgsConstructor
public class AsmePersonTrainCourseServiceImpl extends IBaseServiceImpl<AsmePersonTrainCourseMapper, AsmePersonTrainCourse> implements AsmePersonTrainCourseService {

    private final AsmePersonTrainCourseMapper asmePersonTrainCourseMapper;

    private final AsmePersonTrainRecordMapper asmePersonTrainRecordMapper;

    private final FileInfoMapper fileInfoMapper;

    @Override
    public Result<AsmePersonTrainCourse> getOneByCondition(String columnName, Object columnValue) {
        LambdaQueryWrapper<AsmePersonTrainCourse> queryWrapper = new LambdaQueryWrapper<>();
        if (columnName.equals("id")) {
            queryWrapper.eq(AsmePersonTrainCourse::getId, columnValue);
        }
        AsmePersonTrainCourse asmePersonTrainCourse = asmePersonTrainCourseMapper.selectOne(queryWrapper);
        return Result.ok(asmePersonTrainCourse);
    }

    @Override
    public Result<IPage<AsmePersonTrainCourse>> getListByConditionsWithPage(AsmePersonTrainCourse conditions) {
        String loginUsername = SecurityContextHolder.getContext().getAuthentication().getName();
        IPage<AsmePersonTrainCourse> iPage = new Page<>(conditions.getCurrentPage(), conditions.getPageSize());
        LambdaQueryWrapper<AsmePersonTrainCourse> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ObjectsUtil.noNullAndEmpty(conditions.getMethod()), AsmePersonTrainCourse::getMethod, conditions.getMethod());
        queryWrapper.eq(ObjectsUtil.noNullAndEmpty(conditions.getLevel()), AsmePersonTrainCourse::getLevel, conditions.getLevel());
        queryWrapper.orderByAsc(AsmePersonTrainCourse::getMethod);
        queryWrapper.orderByAsc(AsmePersonTrainCourse::getSequence);
        asmePersonTrainCourseMapper.selectPage(iPage, queryWrapper);
        iPage.getRecords().forEach(asmePersonTrainCourse -> {
            FileInfo fileInfo = fileInfoMapper.selectOneByKeyWord(asmePersonTrainCourse.getAttachmentUuid());
            if (fileInfo != null) {
                asmePersonTrainCourse.setAttachmentUrl(fileInfo.getUrl());
            }
            setProgress(loginUsername, asmePersonTrainCourse);
            setCreatorAndUpdater(asmePersonTrainCourse);
        });
        return Result.ok(iPage);
    }

    private void setProgress(String username, AsmePersonTrainCourse asmePersonTrainCourse) {
        AsmePersonTrainRecord asmePersonTrainRecord = asmePersonTrainRecordMapper.selectByUsernameAndAsmePersonTrainCourseId(username, asmePersonTrainCourse.getId());
        if (asmePersonTrainRecord == null) {
            asmePersonTrainCourse.setProgress(0);
            asmePersonTrainCourse.setIsStarted(false);
        } else {
            long secondsOver = Duration.between(asmePersonTrainRecord.getStartTime(), LocalDateTime.now()).toSeconds();
            long secondsAll = (long) (asmePersonTrainCourse.getCourseScore() * 60 * 60);
            int floored = Math.toIntExact((100 * secondsOver / secondsAll));
            asmePersonTrainCourse.setProgress(Math.min(floored, 100));
            asmePersonTrainCourse.setIsStarted(true);
        }
    }

    @Override
    public Result<AsmePersonTrainCourse> insertOne(AsmePersonTrainCourse entity) {
        Integer maxSequence = asmePersonTrainCourseMapper.getMaxSequence(entity);
        if (maxSequence == null) {
            entity.setSequence(1);
        } else {
            entity.setSequence(++maxSequence);
        }
        entity.setAttachmentUuid(UUID.randomUUID().toString());
        int inserted = asmePersonTrainCourseMapper.insert(entity);
        setCreatorAndUpdater(entity);
        return inserted > 0 ? Result.ok(entity) : Result.error();
    }

    @Override
    public Result<AsmePersonTrainCourse> updateOne(AsmePersonTrainCourse entity) {
        setVersion(entity);
        int updated = asmePersonTrainCourseMapper.updateById(entity);
        setCreatorAndUpdater(entity);
        return updated > 0 ? Result.ok(entity) : Result.error();
    }
}
